/**
 * Copyright(c) 2014 Xunton Solutions
 *
 * History:
 *   15-9-28 上午11:46 Created by dwzhang
 */
package com.jade.bss.weixin.api.token;

import javax.inject.Inject;
import javax.inject.Named;

import com.jade.bss.weixin.WeixinApp;
import com.jade.bss.weixin.WeixinException;
import com.jade.bss.weixin.api.protocol.json.JsonApi;
import com.jade.bss.weixin.api.token.protocol.AccessToken;
import com.jade.bss.weixin.api.token.protocol.ApiTicket;
import com.jade.bss.weixin.api.token.protocol.UserAccessToken;
import com.jade.framework.base.util.HttpUtils;
import com.jade.framework.cache.CacheService;
import com.jade.framework.cache.CacheUtils;

/**
 * Token相关的接口。
 *
 * @author <a href="mailto:dwzhang@xunton.com">dwzhang</a> 
 * @version 1.0 15-9-28 上午11:46
 */
@Named ("bss_weixinTokenApi")
public class TokenApi
        extends JsonApi
{
    private final static String KEY_ACCESS_TOKEN = "bss.weixin.token.access";
    private final static String KEY_API_TICKET = "bss.weixin.token.api_ticket";
    private CacheService cacheService;
    private String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
    private String apiTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card&access_token=";
    private int timeOut = 6000;

    @Inject
    public void setCacheService(@Named ("system_cacheService") CacheService cacheService)
    {
        this.cacheService = cacheService;
    }

    public String getAccessToken(String appCode)
            throws WeixinException
    {
        return getAccessToken(getApp(appCode));
    }

    public String getAccessToken(WeixinApp app)
            throws WeixinException
    {
        String cacheKey = CacheUtils.joinKey(KEY_ACCESS_TOKEN, app.getAppId());
        String token = cacheService.get(cacheKey);
        if (token == null) {
            String url = tokenUrl + "&appid=" + app.getAppId() + "&secret=" + app.getAppSecret();
            AccessToken accessToken = get(url, AccessToken.class);
            token = accessToken.getToken();
            timeOut = timeOut < accessToken.getExpires() ? timeOut : accessToken.getExpires();
            cacheService.set(cacheKey, token, timeOut);
        }
        return token;
    }

    public String refreshAccessToken(String appCode)throws WeixinException
    {
        return refreshAccessToken(getApp(appCode));
    }

    public String refreshAccessToken(WeixinApp app)
    throws WeixinException{
        String cacheKey = CacheUtils.joinKey(KEY_ACCESS_TOKEN, app.getAppId());
        cacheService.delete(cacheKey);
        return getAccessToken(app);
    }

    public UserAccessToken getUserAccessToken(String appCode, String code)
            throws WeixinException
    {
        return getUserAccessToken(getApp(appCode), code);
    }

    public UserAccessToken getUserAccessToken(WeixinApp app, String code)
            throws WeixinException
    {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + app.getAppId() +
                "&secret=" + app.getAppSecret() + "&code=" + code + "&grant_type=authorization_code";
        return get(url, UserAccessToken.class);

    }

    public String getApiTicket(String appCode)
            throws Exception
    {
        return getApiTicket(getApp(appCode));
    }

    public String getApiTicket(WeixinApp app)
            throws Exception
    {
        String accessToken = getAccessToken(app);
        String cacheKey = CacheUtils.joinKey(KEY_API_TICKET, app.getAppId());
        String ticket = cacheService.get(cacheKey);
        if (ticket == null) {
            String url = apiTicketUrl + accessToken;
            ApiTicket response = HttpUtils.getHttp(url, ApiTicket.class);
            ticket = response.getTicket();
            timeOut = timeOut < response.getExpiresIn() ? timeOut : response.getExpiresIn();
            cacheService.set(cacheKey, ticket, timeOut);
        }
        return ticket;
    }

    public String getTokenUrl()
    {
        return tokenUrl;
    }

    public void setTokenUrl(String tokenUrl)
    {
        this.tokenUrl = tokenUrl;
    }

    public String getApiTicketUrl()
    {
        return apiTicketUrl;
    }

    public void setApiTicketUrl(String apiTicketUrl)
    {
        this.apiTicketUrl = apiTicketUrl;
    }

    public int getTimeOut()
    {
        return timeOut;
    }

    public void setTimeOut(int timeOut)
    {
        this.timeOut = timeOut;
    }
}
